home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Creative Computers
/
Creative Computers CD-ROM, Volume 1 (Legendary Design Technologies, Inc.)(1994).iso
/
text
/
misc
/
how2code.txt.pp
/
how2code.txt
Wrap
Text File
|
1994-11-17
|
12KB
|
418 lines
How to write demos that work
============================
(or How to bash the metal and get away with it)
by Comrade J, Share and Enjoy (retired)
Are you fed up of downloading a new demo, running it and finding
your Amiga power light sitting there flashing at you? Are you
tired of the contents of your chipram flashing through the bitplane
registers in a rather random fashion when you run 'Duffex's
Megademo'?
Do you want demos that actually run? Because I do. I'm fed up
completely with all these rubbish coders who can't do their job
properly...
Now, since those long days and nights bashing away at Share and Enjoy
demos I've been involved in all sorts of Amiga programming, involving
new AGA machines, CD, 16-bit audio and all sorts of other
wonderful things that I can't talk about, both via the OS and at a
hardware level.
Most demos I've seen use similar startup code to that I was using back
in 1988. Hey guys, wake up! The Amiga has changed quite a bit since
then.
So. Here are some tips on what to do and what not to do:
1. RTFM.
========
Read the F**king manuals. All of them. Borrow them off friends or from
your local public library if you have to. Make sure you follow the
hardware rules to the letter. If it says "Leave this bit cleared" then
don't set it!
There is a lot of useful informatiton in the 'boring' OS Rom Kernal
Manuals that you may be suprised to know.
Read the "General Amiga Development Guidelines" in the new (grey)
Hardware Reference Manual and follow them TO THE LETTER.
Don't use self-modifying code. A common bit of code I see is:
... in the setup code
move.l $6c.w,old
... at the end of the interrupt
movem.l (sp)+,a0-a6/d0-d7
dc.w $4ef9 ; jmp instruction
old dc.l 0 ; self modifying!!!!
DONT DO THIS!
This is much better (although it still hits $6c which is not a
good thing - It's much better to use AddIntServer() to call your
interrupts, but more on that next time....)
... in the setup code
move.l $6c.w,old
... at the end of the interrupt
movem.l (sp)+,a0-a6/d0-d7
move.l old,-(sp) ; push old address to stack
rts
... in your data section
old dc.l 0
68020 and above processors with cache enabled often barf at the first
piece of code (the cache still contains the JMP 0 instruction
which isn't then altered), but the second piece works fine on the '040.
2. Proper Copper startup.
=========================
IF you are going to use the copper then this is how you should set it
up. The current workbench view and copper address are stored, the
system frozen, and then the copper enabled. On exit the workbench
view is restored.
This guarantees your demo will run on an AGA (Amiga 1200) machine,
even if set into some weird screenmode before running your code.
Otherwise under AGA, the hardware registers can be in some strange states
before your code runs, beware!
The LoadView(NULL) forces the display to a standard, empty position,
flushing the crap out of the hardware registers: Note. There is
a bug in the V39 OS on Amiga 1200/4000 and the sprite resolution is
*not* reset, you will have to do this manually if you use sprites...
Two WaitTOF() calls are needed after the LoadView to wait for both the
long and short frame copperlists of interlaced displays to finish.
I'm writing this code off the top of my head, if you spot any obvious bugs
email me at the address below, or leave mail to me on Bad Dreams BBS.
include "exec/macros.i"
include "exec/funcdef.i" ; keep code simple and
include "exec/exec_lib.i" ; easy to read - use
include "graphics/gfxbase.i" ; the includes!
include "graphics/gfx_lib.i"
include "misc/easystart.i" ; Allows startup from
; icon
section mycode,code ; need not be in chipram
StartCopper:
move.l 4.w,a6 ; get ExecBase
lea gfxname,a1 ; graphics name
moveq #0,d0 ; any version
jsr _LVOOpenLibrary(a6)
tst.l d0
beq End ; failed to open? Then quit
move.l d0,gfxbase
move.l d0,a6
move.l gb_ActiView(a6),wbview
; store current view address
; gb_ActiView = 32
move.l gb_LOFlist(a6),wbcop
; store current wb copper
; gb_LOFlist = 48
move.w #0,a1 ; clears full long-word
jsr _LVOLoadView(a6) ; Flush View to nothing
jsr _LVOWaitTOF(a6) ; Wait once
jsr _LVOWaitTOF(a6) ; Wait again.
; Now you can hit the copper!
move.l 4.w,a6
jsr _LVOForbid(a6) ; Suspend multitasking!
move.l mycopper,$dff080 ; bang it straight in.
; (DO NOT F**K WITH GFXBASE!)
*** DO YOUR FUNKY STUFF HERE ***
CloseDown: move.l 4.w,a6
jsr _LVOPermit(a6) ; Enable multitasking
move.l wbview,a1
move.l gfxbase,a6
jsr _LVOLoadView(a6) ; Fix view
move.l wbcop,$dff080 ; Kick it into life
move.l a6,a1
move.l 4.w,a6
jsr _LVOCloseLibrary(a6) ; EVERYONE FORGETS THIS!!!!
End: rts
section mydata,data_C ; keep data & code seperate!
copperlist dc.w $180,0 ; background black
dc.w $5c07,$fffe ; wait for $5c07,$fffe
dc.w $180,$ff0 ; background yellow
dc.w $ffff,$fffe
dc.w $ffff,$fffe ; Copper end (always do two
; copper end cmds!)
wbview dc.l 0
wbcop dc.l 0
gfxbase dc.l 0
gfxname dc.b "graphics.library",0
3. Your code won't run from an icon.
====================================
You stick an icon for your new demo (not everyone uses the CLI!) and
it either crashes or doesn't give back all the RAM it uses. Why?
Icon startup needs specific code to reply to the workbench message.
With the excellent Hisoft Devpac assember, all you need to do is add
the line
include "misc/easystart.i"
and it magically works!
For those without Devpac, here is the relevent code:
---------------------------------------------------------
* some startup code to make a Workbench execute look like the CLI
* based loosely on RKM Vol 1 page 4-36
* Include this at the front of your program
* after any other includes
* note that this needs exec/exec_lib.i
IFND EXEC_EXEC_I
include "exec/exec.i"
ENDC
IFND LIBRARIES_DOSEXTENS_I
include "libraries/dosextens.i
ENDC
movem.l d0/a0,-(sp) save initial values
clr.l returnMsg
sub.l a1,a1
move.l 4.w,a6
jsr _LVOFindTask(a6) find us
move.l d0,a4
tst.l pr_CLI(a4)
beq.s fromWorkbench
* we were called from the CLI
movem.l (sp)+,d0/a0 restore regs
bra end_startup and run the user prog
* we were called from the Workbench
fromWorkbench
lea pr_MsgPort(a4),a0
move.l 4.w,a6
jsr _LVOWaitPort(A6) wait for a message
lea pr_MsgPort(a4),a0
jsr _LVOGetMsg(A6) then get it
move.l d0,returnMsg save it for later reply
* do some other stuff here RSN like the command line etc
nop
movem.l (sp)+,d0/a0 restore
end_startup
bsr.s _main call our program
* returns to here with exit code in d0
move.l d0,-(sp) save it
tst.l returnMsg
beq.s exitToDOS if I was a CLI
move.l 4.w,a6
jsr _LVOForbid(a6)
move.l returnMsg(pc),a1
jsr _LVOPermit(a6)
exitToDOS
move.l (sp)+,d0 exit code
rts
* startup code variable
returnMsg dc.l 0
* the program starts here
even
_main
---------------------------------------------------------
4. How do I tell if I'm running on an Amiga 1200/4000?
======================================================
Do *NOT* check library revision numbers, V39 OS can and does
run on standard & ECS chipset machines (This Amiga 3000
is currently running V39).
This code will check for AGA
move.w $dff07c,d0
and.w #$ff,d0
cmp.w #$f8,d0
bne.s .notaga
; Do your funky AGA Stuff in here!
.notaga
5. Use Relocatable Code
=======================
If you write demos that run from a fixed